package examples;

import java.util.*;

import project.Project;
import uml2.kernel.*;
import facade.UserFacade;
import facade.kernel.*;

public class humanRightsExample {

	public static void main(String[] args) throws Exception{
		
		System.out.println("===================================");
		System.out.println("======= HUMAN RIGHTS SYSTEM =======");
		System.out.println("===================================");
		System.out.println("==== Example of the Start Guide ===\n");
		
		System.out.println("Project is being created...");
		Project p = new Project("Human Rights System");
		System.out.println("The project "+p.getName()+" has been created\n");
		
		System.out.println("The initial model is being imported to the project");
		p.importXMI("/Users/lotendil/Desktop/models/HumanRightsSystem_initial_einaGMC.xmi");
		//p.importXMI("generat_previ_einaGMC.xmi");
		System.out.println("The initial model has been imported\n");
		
		//Creating Obligation class
		UmlClassFacade ucf = new UmlClassFacade(p);
		UmlClass obligation = ucf.createUmlClass();
		obligation.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		obligation.setName("Obligation");
		System.out.println("Obligation class has been added to the project\n");
		
		//We find the Right and Human classes
		UserFacade uf = new UserFacade(p);
		UmlClass right = uf.findClassByName("Right");
		UmlClass human = uf.findClassByName("Human");
		System.out.println("Right and Human classes have been located\n");
		
		//Creating the "forcesRespecting" association
		AssociationFacade af = new AssociationFacade(p);
		
		PropertyFacade pf = new PropertyFacade(p);
		
		Property p1 = pf.createProperty();
		p1.setName("guarantedRight");
		p1.setType(right);
		p1.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		p1.setAggregation(uml2.kernel.AggregationKindEnum.NONE);
		
		Property p2 = pf.createProperty();
		p2.setType(obligation);
		p2.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		p2.setAggregation(uml2.kernel.AggregationKindEnum.NONE);
		
		LiteralIntegerFacade lif = new LiteralIntegerFacade(p);
		LiteralInteger loweronemultiplicity1 = lif.createLiteralInteger();
		LiteralInteger upperonemultiplicity1 = lif.createLiteralInteger();
		LiteralInteger loweronemultiplicity2 = lif.createLiteralInteger();
		LiteralInteger upperonemultiplicity2 = lif.createLiteralInteger();
		loweronemultiplicity1.setValue(1);
		loweronemultiplicity1.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		upperonemultiplicity1.setValue(1);
		upperonemultiplicity1.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		loweronemultiplicity2.setValue(1);
		loweronemultiplicity2.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		upperonemultiplicity2.setValue(1);
		upperonemultiplicity2.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		p1.setLowerValue(loweronemultiplicity1);
		p1.setUpperValue(upperonemultiplicity1);
		p2.setLowerValue(loweronemultiplicity2);
		p2.setUpperValue(upperonemultiplicity2);

		
		Collection associationEnds = new LinkedList();
		associationEnds.add(p1);
		associationEnds.add(p2);
		Association a = af.createAssociation(associationEnds);
		a.setName("forcesRespecting");
		a.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		System.out.println("forcesRespecting association has been added to the project\n");
		
		//Creating the "mustFulfil" association

		Property p3 = pf.createProperty();
		p3.setName("humanObligations");
		p3.setType(obligation);
		p3.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		p3.setAggregation(uml2.kernel.AggregationKindEnum.NONE);
		
		Property p4 = pf.createProperty();
		p4.setType(human);
		p4.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		p4.setAggregation(uml2.kernel.AggregationKindEnum.NONE);
		
		LiteralInteger lowermultiplicity3 = lif.createLiteralInteger();
		LiteralInteger uppermultiplicity3 = lif.createLiteralInteger();
		LiteralInteger lowermultiplicity4 = lif.createLiteralInteger();
		LiteralInteger uppermultiplicity4 = lif.createLiteralInteger();
		lowermultiplicity3.setValue(0);
		lowermultiplicity3.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		uppermultiplicity3.setValue(-1);
		uppermultiplicity3.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		lowermultiplicity4.setValue(0);
		lowermultiplicity4.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		uppermultiplicity4.setValue(-1);
		uppermultiplicity4.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		
		p3.setLowerValue(lowermultiplicity3);
		p3.setUpperValue(uppermultiplicity3);
		p4.setLowerValue(lowermultiplicity4);
		p4.setUpperValue(uppermultiplicity4);
		
		Collection associationEnds2 = new LinkedList();
		associationEnds2.add(p3);
		associationEnds2.add(p4);
		Association a2 = af.createAssociation(associationEnds2);
		a2.setName("mustFulfil");
		a2.setVisibility(uml2.kernel.VisibilityKindEnum.PUBLIC);
		
		System.out.println("mustFulfil association has been added to the project\n");
		
		

		System.out.println("Parsing and adding the new constraint\n");
		//Creating the new OCL Integrity Constraint
		//The following operation automatically instantiates all the elements
		//necessary to add the constraint.
		String constraint = "context Human inv everybodyMustFulfilAllObligations:Human.allInstances()->forAll(h| h.humanObligations=Obligation.allInstances())";
		
		uf.addOclExpression(constraint, p);
		System.out.println("The constraint \"everybodyMustFulfilAllObligations\" has been added to the project\n");
		
		//Printing the name of all the classes
		Collection classesList = uf.getAllClasses();
		Iterator it = classesList.iterator();
		while (it.hasNext()){
			UmlClass currentClass = (UmlClass)it.next();
			System.out.println(currentClass.getName());
		}
		
		System.out.println("Constraint: \n"+uf.getStringOclExpression("everybodyMustFulfilAllObligations", p));
		System.out.println();
		
		//Save the model
		p.saveXMI("/Users/lotendil/Desktop/models/humanRightsSystem_complete_einaGMC.xmi");
		//p.saveXMI("generat_einaGMC.xmi");
		p.closeProject();
		
		System.out.println("The project has been saved to humanRightsSystem_complete_einaGMC.xmi\n");
		
		System.out.println("===================================");
		System.out.println("Human rights system example finished !");
		System.out.println("===================================");
		
	}

}
